/*
Disclaimer for the National Film Board of Canada and Turbulent Media inc's NFBPlayer:

TERMS OF USE - NFBPlayer

Open source under the BSD License.

Copyright © 2008-2009 Turbulent Media inc. and the NFB of Canada. 
All rights reserved.

Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met:

    * Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer.
    * Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution.
    * Neither the name of the author, copyright holders nor the names of contributors may be used to endorse or promote products derived from this software without specific prior written permission.

THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/

package
{
	import ca.nfb.media.nfbPlayer.ComModule;
	import ca.nfb.media.nfbPlayer.NFBPyroBrew;
	import ca.nfb.media.nfbPlayer.accessibility.ScreenReaderManager;
	import ca.nfb.media.nfbPlayer.net.Tracker;
	import ca.nfb.media.nfbPlayer.ui.HitZone;
	import ca.nfb.media.nfbPlayer.ui.PlaylistRollOver;
	import ca.nfb.media.nfbPlayer.ui.TabIndexManager;
	import ca.nfb.media.nfbPlayer.ui.ToolTip;
	import ca.nfb.media.nfbPlayer.utils.KeysHandler;
	import ca.nfb.media.nfbPlayer.views.*;
	import ca.turbulent.media.Pyro;
	import ca.turbulent.media.events.PyroEvent;
	import ca.turbulent.media.events.ErrorEvent;
	import ca.turbulent.media.events.StatusUpdateEvent;
	import ca.turbulent.text.SuperText;
	
	import flash.display.LoaderInfo;
	import flash.display.MovieClip;
	import flash.display.StageAlign;
	import flash.display.StageQuality;
	import flash.display.StageScaleMode;
	import flash.events.ContextMenuEvent;
	import flash.events.Event;
	import flash.events.FullScreenEvent;
	import flash.events.TimerEvent;
	import flash.external.ExternalInterface;
	import flash.system.Security;
	import flash.ui.ContextMenu;
	import flash.ui.ContextMenuBuiltInItems;
	import flash.ui.ContextMenuItem;
	import flash.utils.Timer;
	/**
	 * 
	 * @author Eric Poirier
	 * 
	**/

	public class NFBPlayer extends MovieClip
	{
		public static const DEFAULT_STATE			:String = "defaultView";
		public static const END_PLAYLIST_STATE		:String = "endDefaultState";
		public static const OPTIONS_STATE			:String = "optionsState";
		public static const MORE_INFOS_STATE		:String = "moreInfosState";
		public static const SHARING_STATE			:String = "sharingState";
		public static const PREVIEW_IMAGE_STATE		:String = "previewImageState";
		public static const FILE_NOT_FOUND_STATE	:String = "fileNotFoundState";
		public static const MESSAGE_STATE			:String = "messageState";
		
		public static const STATE_UPDATE_EVENT		:String = "stateUpdateEvent";
		
		public static var ALLOWED_DOMAINS			:Array = new Array();
		public static var AUDIO_MIN_BUFFER_RATIO	:Number = .2;
	
		public static const URL_FROM_NFB_PACKAGE	:String = "nfbProvidedURL";
		public static const URL_STANDARD			:String = "standardURL";
		
		public static const VERSION					:String = "2.1.1";
		
		private var _autoLoadAudioDescription		:Boolean = false; 
		private var _backgroundAlpha				:Number = 1;
		private var _backgroundColor				:Number = 0x000000;
		private var _currentState					:String;
		private var _firstRun						:Boolean = true;
		public var _movieID							:String = "";
		private var _outlineColor					:Number = 0x333333;
		private var _outlineThickness				:Number = 2;
		private var _outlineAlpha					:Number = 1;
		private var _playlistID						:String = "";
		private var _registeredViews				:Object = new Object();
		private var _warningMessage					:String = "";
		
		private var initTimer 						:Timer = new Timer(100, 1);
		public var minimumWidth						:Number = 20;
		public var minimumHeight					:Number = 10;
		private var outline_mc						:MovieClip = new MovieClip();
		
		public var NFBContextMenu					:ContextMenu;
		private var deblockOnMenuItem				:ContextMenuItem;
		private var deblockOffMenuItem				:ContextMenuItem;
		private var smoothingOnMenuItem				:ContextMenuItem;
		private var smoothingOffMenuItem			:ContextMenuItem;
		
		public var audioDescriptionOn				:Boolean = false;
		public var autoDetectFlashVersion			:Boolean = true;
		public var controllerHeight					:Number = 47;
		
		public var captionsOn						:Boolean = false;
		public var background_mc					:MovieClip = new MovieClip();
		public var bookmarksURL						:String = "";
		public var controlBar						:ControlBar;
		public var enableJavascriptAPI				:Boolean = false;
		public var hasBackgroundAndOutline			:Boolean = true;
		public var hasCascadingURLBusinessLogic		:Boolean = true;
		public var hitZone							:HitZone;
		public var enablePlayButton					:Boolean = true;
		public var enableVolumeButton				:Boolean = true;
		public var enableSpeedOptionsButton			:Boolean = false;
		public var enableCloseCaptionsButton		:Boolean = true;
		public var enableMoreInfosButton			:Boolean = false;
		public var enableDescriptiveAudioButton		:Boolean = false;
		public var enableSharingButton				:Boolean = false;
		public var enableCartButton					:Boolean = false;
		public var embeddedMode						:Boolean = false;
		public var resizable						:Boolean = false;
		public var widgetMode						:Boolean = false;
		
		public var directURL 						:String = "";
		public var directCCURL						:String = "";
		public var directDVURL						:String = "";
		public var directCCDVURL					:String = "";
		
		public var getPlaylistOnEnd					:Boolean = false;
		public var isSmaller						:Boolean = false;
		public var mainFont							:ITCFont = new ITCFont();
		public var minimalWidthForPanel				:Number = 516;
		public var minimalHeightForPanel			:Number = 337;
		
		public var movieInfosTitle					:String = "";
		public var movieInfosDescription			:String = "";
		
		public var overlayedPanelOpen				:Boolean = false;
		public var pageURL							:String = "";
		public var playlist							:Array	= new Array();
		public var previewImageURL					:String = "";
		public var showBookmarks					:Boolean = true;
		public var showControls						:Boolean = true;
		public var showPreviewImage					:Boolean = true;
		public var showWarningMessages				:Boolean = true; 
		public var showWatermark					:Boolean = false;
		public var showEmbeddedWelcome				:Boolean = false;
		public var trackPageURL						:Boolean = false;
		public var trackPageRefferer				:Boolean = false;
		public var reffererURL						:String = "";
		public var urlType							:String;
		public var watermarkURL						:String = "";
		public var watermarkAlignMode				:String = "bottomRight";
		public var watermarkAlpha					:Number = 1;
		public var watermarkVPadding				:Number = 0;
		public var watermarkHPadding				:Number = 0;	
		public var wasPaused						:Boolean = false;
		public var requestedSizes					:Object = new Object();
	
		public var player							:NFBPyroBrew; 
		public var previewImage						:PreviewImage;
		public var embeddedWelcomeView				:EmbedWelcome;
		public var fullModalView					:FullModalView;
		public var screenReaderManager				:ScreenReaderManager = new ScreenReaderManager();
		public var sharingView						:Sharing;
		public var bufferingView					:BufferingView;
		public var tracker							:Tracker;
		public var bigPlayOverlay					:PlayOverlay;
		public var finalPlaylistView				:FinalPlaylist;
		public var keysManager						:KeysHandler;
		public var moreInfoView						:MoreInfo;
		public var optionsView						:Options;
		public var messageView						:MessageView;
		public var notFoundErrorView				:NotFoundErrorView;
		public var playlistOver						:PlaylistRollOver;
		public var tabManager						:TabIndexManager;
		public var toolTip							:ToolTip;
		public var warningMessageView				:Warnings;
		public var watermarkView					:Watermark;
		public var welcomeEmbed						:EmbedWelcome;
		public var insufficientBWView				:InsufficientBandwidthView;
		
		public function NFBPlayer():void
		{
			stage.align = StageAlign.TOP_LEFT;
			stage.scaleMode = StageScaleMode.NO_SCALE;
			_currentState = NFBPlayer.DEFAULT_STATE;
			addEventListener(Event.ADDED_TO_STAGE, addedToStage, false, 0, true);
		}
		
		private function addedToStage(evt:Event):void
		{
			startInitTimer();
		}
		
		private function startInitTimer(evt:Event=null):void
		{
			if (initTimer.hasEventListener(TimerEvent.TIMER_COMPLETE))
				initTimer.removeEventListener(TimerEvent.TIMER_COMPLETE, initTimerDone);
				
			initTimer.addEventListener(TimerEvent.TIMER_COMPLETE, initTimerDone, false, 0, true);
			initTimer.start();
		}
		
		private function initTimerDone(evt:TimerEvent):void
		{
			if (stage.stageWidth > 0 && stage.stageHeight > 0)
				initializeAll();
			else
				startInitTimer();
		}
		
		/*
		*  Init methods and views registration handling.
		*/ 
		
		private function initializeAll():void
		{
			if (stage.stageWidth < minimalWidthForPanel || stage.stageHeight < minimalHeightForPanel)
				isSmaller = true;
				
			ComModule.getInstance().registerCore(this);
			removeEventListener(Event.ADDED_TO_STAGE, addedToStage);
			allowAccess();
			applyStageParameters();
			drawCanvas();
			initPlayer();
			drawNFBContextMenu();
		}
		
		private function allowAccess():void
		{
			Security.allowDomain('*');
			Security.allowInsecureDomain('*');
			
			var p:Object = LoaderInfo(stage.loaderInfo).parameters;
			var parsedDomains:Array = new Array();
			var i:Number=0;
			if (p.allowedDomains)
			{
				parsedDomains = String(p.allowedDomains).split(",");
				for (i=0; i<parsedDomains.length; ++i)
					ALLOWED_DOMAINS.push(parsedDomains[i]);
			}
				
			for (i=0; i<ALLOWED_DOMAINS.length; ++i) Security.allowDomain(ALLOWED_DOMAINS[i]);
			
			var policyFiles:Array = new Array();
			
			if (p.policyFiles)
			{
				policyFiles = String(policyFiles).split(",");
				for (var j:Number=0; j<policyFiles.length; ++j)
					Security.loadPolicyFile(policyFiles[j]);
			}
			
			// Security.loadPolicyFile(policyFileURL.xml);
		}
		
		
		private function applyStageParameters():void
		{
			var p:Object = LoaderInfo(stage.loaderInfo).parameters;
			
			if (p.lang != null && p.lang != "" && p.lang != ComModule.getLang() && (String(p.lang).toUpperCase() == "FR" || String(p.lang).toUpperCase() == "EN"))
				ComModule.setLang(String(p.lang).toUpperCase());
				
			if ((p.enableJavascriptAPI == "true" || p.enableJavascriptAPI == "false") && p.enableJavascriptAPI != enableJavascriptAPI)
				enableJavascriptAPI = Boolean(p.enableJavascriptAPI == "true");
				
			if ((p.autoDetectFlashVersion == "true" || p.autoDetectFlashVersion == "false") && p.autoDetectFlashVersion != autoDetectFlashVersion)
				autoDetectFlashVersion = Boolean(p.autoDetectFlashVersion=="true");	
			
			if ((p.trackPageURL == "true" || p.trackPageURL == "false") && p.trackPageURL != trackPageURL)
				trackPageURL = Boolean(p.trackPageURL=="true");
			
			if (p.pageURL != null && p.pageURL != "")
				pageURL = p.pageURL;
				
			if ((p.trackPageRefferer == "true" || p.trackPageRefferer == "false") && p.trackPageRefferer != trackPageRefferer)
				trackPageRefferer = Boolean(p.trackPageRefferer=="true");
			
			if (p.reffererURL != null && p.reffererURL != "")
				reffererURL = p.reffererURL;
			
			if (p.backgroundColor != null && p.backgroundColor != "" && Number(p.backgroundColor) != backgroundColor)
				backgroundColor = Number(p.backgroundColor);
				
			if (p.backgroundAlpha != null && p.backgroundAlpha != "" && Number(p.backgroundAlpha) != backgroundAlpha)
				backgroundAlpha = Number(p.backgroundAlpha);
				
			if (p.hasBackgroundAndOutline != null && p.hasBackgroundAndOutline != "" && (p.hasBackgroundAndOutline == "true" || p.hasBackgroundAndOutline == "false"))
				hasBackgroundAndOutline = Boolean(p.hasBackgroundAndOutline == "true");
			
			if (p.outlineColor != null && p.outlineColor != "" && Number(p.outlineColor) != outlineColor)
				outlineColor = Number(p.outlineColor);
				
			if (p.outlineAlpha != null && p.outlineAlpha != "" && Number(p.outlineAlpha) != outlineAlpha)
				outlineAlpha = Number(p.outlineAlpha);
				
			if (p.outlineThickness != null && p.outlineThickness != "" && Number(p.outlineThickness) != outlineThickness)
				outlineThickness = Number(p.outlineThickness);
			
			if (p.enablePlayButton != null && p.enablePlayButton != "" && (p.enablePlayButton == "true" || p.enablePlayButton == "false"))
				enablePlayButton = Boolean(p.enablePlayButton=="true");
			
			if (p.enableVolumeButton != null && p.enableVolumeButton != "" && (p.enableVolumeButton == "true" || p.enableVolumeButton == "false"))
				enableVolumeButton = Boolean(p.enableVolumeButton=="true");
			
			if (p.enableSpeedOptionsButton != null && p.enableSpeedOptionsButton != "" && (p.enableSpeedOptionsButton == "true" || p.enableSpeedOptionsButton == "false"))
				enableSpeedOptionsButton = Boolean(p.enableSpeedOptionsButton=="true");
			
			if (p.enableMoreInfosButton != null && p.enableMoreInfosButton != "" && (p.enableMoreInfosButton == "true" || p.enableMoreInfosButton == "false"))
				enableMoreInfosButton = Boolean(p.enableMoreInfosButton=="true");
			
			if (p.enableDescriptiveAudioButton != null && p.enableDescriptiveAudioButton != "" && (p.enableDescriptiveAudioButton == "true" || p.enableDescriptiveAudioButton == "false"))
				enableDescriptiveAudioButton = Boolean(p.enableDescriptiveAudioButton=="true");
				
			if (p.enableCloseCaptionsButton != null && p.enableCloseCaptionsButton != "" && (p.enableCloseCaptionsButton == "true" || p.enableCloseCaptionsButton == "false"))
				enableCloseCaptionsButton = Boolean(p.enableCloseCaptionsButton=="true");
				
			if (p.enableSharingButton != null && p.enableSharingButton != "" && (p.enableSharingButton == "true" || p.enableSharingButton == "false"))
				enableSharingButton = Boolean(p.enableSharingButton=="true");	
				
			if (p.enableCartButton != null && p.enableCartButton != "" && (p.enableCartButton == "true" || p.enableCartButton == "false"))
				enableCartButton = Boolean(p.enableCartButton =="true");
				
			/* if (p.getPlaylistOnEnd != null && p.getPlaylistOnEnd != "" && (p.getPlaylistOnEnd == "true" || p.getPlaylistOnEnd == "false"))
				getPlaylistOnEnd = Boolean(p.getPlaylistOnEnd =="true"); */		
			
			if (p.showPreviewImage != null && p.showPreviewImage != "" && (p.showPreviewImage == "true" || p.showPreviewImage == "false"))
				showPreviewImage = Boolean(p.showPreviewImage =="true");
			
			if (p.image != null && p.image != "" && p.image != previewImageURL)
				previewImageURL = p.image;
					
			if (p.bookmarksURL != null && p.bookmarksURL != "" && p.bookmarksURL != bookmarksURL)
				bookmarksURL = p.bookmarksURL;	
		
			if (p.showBookmarks != null && p.showBookmarks != "" && (p.showBookmarks == "true" || p.showBookmarks == "false"))
				showBookmarks = Boolean(p.showBookmarks =="true");
				
			//override image.	
			if (p.previewImageURL != null && p.previewImageURL != "" && p.previewImageURL != previewImageURL)
				previewImageURL = p.previewImageURL;
				
			if (p.playlist_id != null && p.playlist_id !="" && p.playlist_id != playlistID)
				_playlistID = p.playlist_id;
			
			if (p.showWarningMessages != null && p.showWarningMessages != "" && (p.showWarningMessages == "true" || p.showWarningMessages == "false"))
				showWarningMessages = Boolean(p.showWarningMessages == "true");	
			
			if (p.warningMessage != null && p.warningMessage !="" && p.warningMessage != warningMessage)
				_warningMessage = p.warningMessage;
			
			if (p.showEmbeddedWelcome != null && p.showEmbeddedWelcome != "" && (p.showEmbeddedWelcome == "true" || p.showEmbeddedWelcome == "false"))
				showEmbeddedWelcome = Boolean(p.showEmbeddedWelcome == "true");	
			
			if (p.embeddedMode != null && p.embeddedMode != "" && (p.embeddedMode == "true" || p.embeddedMode == "false"))
				embeddedMode = Boolean(p.embeddedMode == "true");	
			
			if (p.widgetMode != null && p.widgetMode != "" && (p.widgetMode == "true" || p.widgetMode == "false"))
				widgetMode = Boolean(p.widgetMode == "true");	
			
			if (p.resizable != null && p.resizable != "" && (p.resizable == "true" || p.resizable == "false"))
				resizable = Boolean(p.resizable == "true");	
			
			if (p.movieInfosTitle != null && p.movieInfosTitle != "")
				ComModule.getInstance().currentMovieInfos.title = movieInfosTitle;
			
			if (p.movieInfosDescription != null && p.movieInfosDescription != "")
				ComModule.getInstance().currentMovieInfos.description = movieInfosDescription;
			
			
			
			if (p.fileURL != null && p.fileURL != "")
			{
				directURL = p.fileURL;
			}
			
			
			if (p.fileCCURL != null && p.fileCCURL != "")
			{
				this.directCCURL = p.fileCCURL;
				ComModule.getInstance().packageFromURL = true;
				this.enableCloseCaptionsButton = true;
				
			}	
			if (p.fileDVURL != null && p.fileDVURL != "")
			{
				ComModule.getInstance().packageFromURL = true;
				this.directDVURL = p.fileDVURL;
				this.enableDescriptiveAudioButton = true;
			}
				
			if (p.fileCCDVURL != null && p.fileCCDVURL != "")
			{
				ComModule.getInstance().packageFromURL = true;
				this.enableCloseCaptionsButton = true;
				this.directCCDVURL = p.fileCCDVURL;
			}	
			
			if (embeddedMode && !widgetMode)
				this.showEmbeddedWelcome = true;	
			
			requestedSizes = new Object();
			
			if (p.playerWidth != null && p.playerWidth != "")
			{
				requestedSizes.width = Number(p.playerWidth) < this.minimumWidth ? this.minimumWidth : Number(p.playerWidth);
			}
			else
			{
				if (stage.stageWidth < this.minimumWidth)
					requestedSizes.width = this.minimumWidth;
				else
					requestedSizes.width = stage.stageWidth;
			}
			if (p.playerHeight != null && p.playerHeight != "")
			{
				requestedSizes.height = Number(p.playerHeight) < this.minimumHeight ? this.minimumHeight : Number(p.playerHeight);
			}
			else
			{
				if (stage.stageHeight < this.minimumHeight)
					requestedSizes.height = this.minimumHeight;
				else	
					requestedSizes.height = stage.stageHeight;	
			}
		}	
			
		// External Interfaces calls 
		
		private function setUpExternalInterfaceAPI():void
		{
			ExternalInterface.addCallback("playVideo", JS_playVideo);
			ExternalInterface.addCallback("pauseVideo", player.pause);
			ExternalInterface.addCallback("togglePauseVideo", player.togglePause);
			ExternalInterface.addCallback("stopVideo", player.stop);
			ExternalInterface.addCallback("seekTo", JS_seekVideo);
			ExternalInterface.addCallback("getStateReport", tracker.getStateReport);
		}
		
		private function JS_playVideo(...args):void
		{
			if (args[0] != null)
				player.play(args[0]);
			else
				player.play();
		}
		
		private function JS_seekVideo(...args):void
		{
			player.seek(Number(args[0]));
		} 
		
		
		public function drawCanvas():void
		{
			if (hasBackgroundAndOutline)
			{
				drawOutline(requestedSizes.width, requestedSizes.height);
				drawBackground(requestedSizes.width, requestedSizes.height);
			}
		}
			
		public function drawNFBContextMenu():void
		{
			NFBContextMenu = new ContextMenu();
			NFBContextMenu.hideBuiltInItems();
			
			var label:String = ComModule.getLang() == "FR" ? "Lecteur vidéo ONF vers. "+NFBPlayer.VERSION : "NFB video player vers. "+NFBPlayer.VERSION;
			var nfbMenuItem:ContextMenuItem = new ContextMenuItem(label, false, false, true);
			NFBContextMenu.customItems = [nfbMenuItem]; 
			this.contextMenu = 	NFBContextMenu; 
		}	
			
		private function drawBackground(w:Number, h:Number):void
		{
			if (!this.contains(background_mc))
				addChild(background_mc);
				
			background_mc.graphics.clear();
			background_mc.graphics.beginFill(this.backgroundColor, this.backgroundAlpha);
			background_mc.graphics.drawRect(outlineThickness, outlineThickness, w-(outlineThickness*2), h-(outlineThickness)-controllerHeight);
			background_mc.graphics.endFill();
		}
		
		private function drawOutline(w:Number, h:Number):void
		{
			if (!this.contains(outline_mc))
				addChild(outline_mc);
				
			outline_mc.graphics.clear();
			outline_mc.graphics.beginFill(this.outlineColor, this.outlineAlpha);
			outline_mc.graphics.drawRect(0, 0, w, h-controllerHeight);
			outline_mc.graphics.endFill();
		}
		
		private function fileURLReceived(evt:Event):void
		{
			
			if (ComModule.getInstance().latestMovieRating != "" && ComModule.getInstance().latestMovieRating != "G")
				this._warningMessage = ComModule.getInstance().latestMovieRating;
				
			if (showWarningMessages && this.warningMessage != "")
				this.warningMessageView.showWarning(this._warningMessage);
			
			/* if (ComModule.getInstance().latestMessages != "")
				this.messageView.show(); */
			
			if (enableCartButton && ComModule.getInstance().latestMovieDirectBuyURL != "")
				controlBar.enableCartButton();
			
			if (showEmbeddedWelcome)
			{
				if (showWarningMessages)
					embeddedWelcomeView.y = stage.stageHeight - (this.controllerHeight+embeddedWelcomeView.height);
				else
					embeddedWelcomeView.y = 0;
					
				embeddedWelcomeView.show();	
					
			}
			
			if (ComModule.getInstance().currentMovieInfos.description != "")
				this.moreInfoView.setTexts();
			
			if (!firstRun)
				_firstRun = false;
				
			if(showPreviewImage && previewImageURL != "")
			{
				this.setCurrentState(NFBPlayer.PREVIEW_IMAGE_STATE);
			}
			else
			{
				if (player.isSwitchingFeed)
				{
					if (player.streamType == Pyro.STREAM_TYPE_PROXIED_PROGRESSIVE && player.timeCache > 0)
					{
						var newURLInfos:Object = player.getParsedURLObject(ComModule.getInstance().latestFileURL);
						if (newURLInfos.protocol == "http:/" || newURLInfos.protocol == "https:/" || newURLInfos.protocol == "httpd:/")
						{
							var startIndex:Number = String(ComModule.getInstance().latestFileURL).indexOf("?start=")
							if (startIndex > 0)
							{
								var tempString:String = String(ComModule.getInstance().latestFileURL).substring(0, startIndex);
								var newURL:String = tempString + "?start="+String(player.timeCache);
								ComModule.getInstance().latestFileURL = newURL;
							}		
						}	
					}
				}
				this.controlBar.setOptionals();
				player.play(ComModule.getInstance().latestFileURL);
			}
		}
		
			
		private function initPlayer():void
		{	
			resizable = true;
			if (resizable)
			{
				stage.scaleMode = StageScaleMode.NO_SCALE;	
				stage.addEventListener(Event.RESIZE, stageResized);
			}

			var localWidth:Number = hasBackgroundAndOutline ? requestedSizes.width-(this.outlineThickness*2) : requestedSizes.width;
			var localHeight:Number = hasBackgroundAndOutline ? requestedSizes.height-(this.outlineThickness) : requestedSizes.height;
			
			if (directURL != "" || directCCURL != "" || directDVURL != "" || directCCDVURL != "")
			{
				urlType = NFBPlayer.URL_STANDARD;
				var hasPackage:Boolean = false;
				
				if (this.directCCURL)
				{
					ComModule.getInstance().latestMovieHasCC = true;
					hasPackage = true;
				}
				
				if (this.directDVURL)
				{
					ComModule.getInstance().latestMovieHasDV = true;
					hasPackage = true;	
				}	
				
				if (this.directCCDVURL)
				{
					ComModule.getInstance().latestMovieHasCCDV = true;
					hasPackage = true;
				}
				
				if (hasPackage)
				{
					
					ComModule.getInstance().latestFileURL = directURL;
					ComModule.getInstance().latestPackage = {normal:{}, low:{}, extreme:{} };
					ComModule.getInstance().packageFromURL = true;
					ComModule.getInstance().latestPackage.normal.url = directURL;
					ComModule.getInstance().latestPackage.extreme.url = directURL;
					ComModule.getInstance().latestPackage.low.url = directURL;
				
					if (ComModule.getInstance().latestMovieHasCC)
					{
						ComModule.getInstance().latestMovieHasCC = true;
						ComModule.getInstance().latestPackage.normal.has_cc = true;
						ComModule.getInstance().latestPackage.low.has_cc = true;
						ComModule.getInstance().latestPackage.extreme.has_cc = true;
						ComModule.getInstance().latestPackage.normal.cc_url = this.directCCURL;
						ComModule.getInstance().latestPackage.low.cc_url = this.directCCURL;
						ComModule.getInstance().latestPackage.extreme.cc_url = this.directCCURL;
					}
					
					if (ComModule.getInstance().latestMovieHasDV)
					{
						ComModule.getInstance().latestMovieHasDV = true;
						ComModule.getInstance().latestPackage.normal.has_dv = true;
						ComModule.getInstance().latestPackage.low.has_dv = true;
						ComModule.getInstance().latestPackage.extreme.has_dv = true;
						ComModule.getInstance().latestPackage.normal.dv_url = this.directDVURL;
						ComModule.getInstance().latestPackage.low.dv_url = this.directDVURL;
						ComModule.getInstance().latestPackage.extreme.dv_url = this.directDVURL;
					}
					
					if (ComModule.getInstance().latestMovieHasCCDV)
					{
						ComModule.getInstance().latestMovieHasCCDV = true;
						ComModule.getInstance().latestPackage.normal.has_cc_dv = true;
						ComModule.getInstance().latestPackage.low.has_cc_dv = true;
						ComModule.getInstance().latestPackage.extreme.has_cc_dv = true;
						ComModule.getInstance().latestPackage.normal.cc_dv_url = this.directCCDVURL;
						ComModule.getInstance().latestPackage.low.cc_dv_url = this.directCCDVURL;
						ComModule.getInstance().latestPackage.extreme.cc_dv_url = this.directCCDVURL;
					}
					
					
				}	
					
			}
			
			if (this.showControls) 
				localHeight -= controllerHeight;
				
			player = new NFBPyroBrew(localWidth, localHeight);
			screenReaderManager.addAccess(player, "Toggle pause on video.", "Mettre la vidéo en pause ou bien jouer la vidéo.");
			registerCommEvents();
			player.x = player.y = this.outlineThickness;
			addChild(player);
			
			hitZone = new HitZone();
			addChild(hitZone);
			
			previewImage = new PreviewImage(localWidth, localHeight);
			addChild(previewImage);
			screenReaderManager.addAccess(previewImage, "Start video", "Jouer la vidéo.");
			
			watermarkView = new Watermark();
			addChild(watermarkView);
			
			tabManager = new TabIndexManager();
			addChild(tabManager);
			
			tabManager.clearFromFocus([player, hitZone, previewImage, watermarkView]);
			
			if (showControls)
			{
				controlBar = new ControlBar(requestedSizes.width);
				controlBar.x = 0;
				controlBar.y = player.height;
				addChild(controlBar);
			}
			else
			{
				this.controllerHeight = 0;
			}

			bufferingView = new BufferingView();
			addChild(bufferingView);
			
			bigPlayOverlay = new PlayOverlay();
			addChild(bigPlayOverlay);
			
			moreInfoView = new MoreInfo();
			addChild(moreInfoView);
			
			optionsView = new Options();
			addChild(optionsView);
			
			sharingView = new Sharing();
			addChild(sharingView);
			
			fullModalView = new FullModalView(true, true);
			addChild(fullModalView);
			
			finalPlaylistView = new FinalPlaylist();
			addChild(finalPlaylistView);
			
			warningMessageView = new Warnings();
			addChild(warningMessageView);
			
			embeddedWelcomeView = new EmbedWelcome();
			addChild(embeddedWelcomeView);
			
			notFoundErrorView = new NotFoundErrorView();
			addChild(notFoundErrorView);
			
			/* messageView = new MessageView();
			addChild(messageView); */
			
			insufficientBWView = new InsufficientBandwidthView();
			addChild(insufficientBWView);
			
			toolTip = new ToolTip();
			addChild(toolTip);
			
			/* playlistOver = new PlaylistRollOver();
			addChild(playlistOver);
			 */
			tracker = new Tracker();
			addChild(tracker);
			
			keysManager = new KeysHandler();
			addChild(keysManager);
			
			if (enableJavascriptAPI)
			{
				setUpExternalInterfaceAPI();
			}
			
			if (directURL != "")
			{
				if (ComModule.getInstance().latestMovieRating != "" && ComModule.getInstance().latestMovieRating != "G")
					this._warningMessage = ComModule.getInstance().latestMovieRating;
			
				if (showWarningMessages && this.warningMessage != "")
					this.warningMessageView.showWarning(this._warningMessage);
				
				if (enableCartButton && ComModule.getInstance().latestMovieDirectBuyURL != "")
					controlBar.enableCartButton();
				
				if (showEmbeddedWelcome)
				{
					if (showWarningMessages)
						embeddedWelcomeView.y = stage.stageHeight - (this.controllerHeight+embeddedWelcomeView.height);
					else
						embeddedWelcomeView.y = 0;
						
					embeddedWelcomeView.show();	
						
				}
				
				if (ComModule.getInstance().currentMovieInfos.description != "")
					this.moreInfoView.setTexts();
				
				if (!firstRun)
					_firstRun = false;
				
				
				var p:Object = LoaderInfo(stage.loaderInfo).parameters;
					
				if(showPreviewImage && previewImageURL != "")
				{
					this.setCurrentState(NFBPlayer.PREVIEW_IMAGE_STATE);
					
					switch (p.fileType)
					{
						case NFBPyroBrew.FILE_TYPE_NORMAL:
						default:
						ComModule.getInstance().latestFileURL = this.directURL;
						break; 
						
						case NFBPyroBrew.FILE_TYPE_CC:
						ComModule.getInstance().latestFileURL = this.directCCURL;
						break;
						
						case NFBPyroBrew.FILE_TYPE_DV:
						ComModule.getInstance().latestFileURL = this.directDVURL;
						break;
						
						case NFBPyroBrew.FILE_TYPE_CCDV:
						ComModule.getInstance().latestFileURL = this.directCCDVURL;
						break;
					}
				}
				else
				{
					
					switch (p.fileType)
					{
						case NFBPyroBrew.FILE_TYPE_NORMAL:
						default:
						player.play(directURL);	
						break; 
						
						case NFBPyroBrew.FILE_TYPE_CC:
						player.play(this.directCCURL);
						break;
						
						case NFBPyroBrew.FILE_TYPE_DV:
						player.play(this.directDVURL);
						this.audioDescriptionOn = true;
						break;
						
						case NFBPyroBrew.FILE_TYPE_CCDV:
						player.play(this.directCCDVURL);
						this.audioDescriptionOn = true;
						break;
					}
				} 	
				// this.controlBar.setTrackOptions();
				// this.controlBar.setOptionals();
			}	
			else
			{
				// urlType = NFBPlayer.URL_STANDARD;
				// player.play("rtmp://flash.nfb.ca/collection4/M1M/bandes-annonces/1000_54268.mp4");
				
				// this.playlistID =  
				// ComModule.getInstance().getMoviePackage('IDOBJ721');
				this.setCurrentState(NFBPlayer.FILE_NOT_FOUND_STATE);
			}
			
			player.addEventListener(NFBPyroBrew.STREAM_QUALITY_CHANGE, speedChanged, false, 0, true);
			player.addEventListener(PyroEvent.COMPLETED, completed, false, 0, true);
			player.addEventListener(ErrorEvent.FILE_NOT_FOUND_ERROR, notFoundErrorHandler, false, 0, true);
			stage.addEventListener(FullScreenEvent.FULL_SCREEN, fullscreenHandler, false, 0, true);
			
			tracker.trackPlayerVersion();
			tracker.trackScreenResolution();
			
			moreInfoView.y = sharingView.y = controlBar.y-281.2;
			optionsView.y = controlBar.y-176.2;
		}
		
		// External Interfaces calls 
		
		private function stageResized(evt:Event):void
		{
			var localWidth:Number = stage.stageWidth;
			var localHeight:Number = stage.stageHeight;
			
			if (localWidth < this.minimumWidth) 
				localWidth = minimumWidth;
				
			if (localHeight < this.minimumHeight) 
				localHeight = minimumHeight;
			
			if (stage.stageWidth < minimalWidthForPanel || stage.stageHeight < minimalHeightForPanel)
				isSmaller = true;
			else
				isSmaller = false;
							
			drawOutline(localWidth, localHeight);
			drawBackground(localWidth, localHeight);
			
			if (localWidth-529 <=7)
				moreInfoView.x = 7;
			else
				moreInfoView.x = localWidth - 529;
		
			if (this.showControls) 
				localHeight -= controllerHeight;	
			
			player.resize(hasBackgroundAndOutline ? localWidth-(outlineThickness*2):localWidth, hasBackgroundAndOutline ? localHeight-(this.outlineThickness):localHeight);
			controlBar.y = stage.stageHeight-controllerHeight;
			moreInfoView.y = sharingView.y = controlBar.y-281.2;
			optionsView.y = controlBar.y-176.2;
		}
		
		private function notFoundErrorHandler(evt:Event):void
		{
			this.setCurrentState(NFBPlayer.FILE_NOT_FOUND_STATE);
		}
		
		private function fullscreenHandler(evt:FullScreenEvent):void
		{
			var localWidth:Number;
			var localHeight:Number;
			
			if (evt.fullScreen)
			{
				localWidth = stage.stageWidth;
				localHeight = stage.stageHeight;
				drawOutline(stage.stageWidth, stage.stageHeight);
				drawBackground(localWidth, localHeight);
				moreInfoView.x = localWidth - 529;
				ComModule.getInstance().setStats("fullscreenToggled: on");
			}
			else
			{
				localWidth = requestedSizes.width;
				localHeight = requestedSizes.height;
				drawOutline(requestedSizes.width, requestedSizes.height);
				drawBackground(requestedSizes.width, requestedSizes.height);
				moreInfoView.x = 7;
				ComModule.getInstance().setStats("fullscreenToggled: off");
			}
			
			if (this.showControls)
				localHeight -= controllerHeight;	
			
			player.resize(hasBackgroundAndOutline ? localWidth-(outlineThickness*2):localWidth, hasBackgroundAndOutline ?localHeight-(this.outlineThickness):localHeight);
			controlBar.y = stage.stageHeight-controllerHeight;
			moreInfoView.y = sharingView.y = controlBar.y-281.2;
			optionsView.y = controlBar.y-176.2;
		}
		
		private function completed(evt:Event):void
		{
			if (this.currentState != NFBPlayer.END_PLAYLIST_STATE && 
				this.currentState != NFBPlayer.OPTIONS_STATE && 
				this.currentState != NFBPlayer.MORE_INFOS_STATE && 
				this.currentState != NFBPlayer.SHARING_STATE)
			{	
				player.pause();
				player.seek(0);
			}
		}
		
		public function registerCommEvents():void
		{
			
		}
		
		public function registerEvents():void
		{
			
		}
		
		
		public function registerView(viewInstanceObj:Object):void
		{
			if (this._registeredViews[viewInstanceObj['instanceName']])
				NFBPlayerView(this._registeredViews[viewInstanceObj['instanceName']]).clear();
				
			this._registeredViews[viewInstanceObj['instanceName']] = viewInstanceObj['instance'];	
		}
		
		public function setCurrentState(str:String):void
		{
			if ((this.currentState == NFBPlayer.MORE_INFOS_STATE ||
				this.currentState == NFBPlayer.OPTIONS_STATE || 
				this.currentState == NFBPlayer.SHARING_STATE) && this.moreInfoView.previousState == NFBPlayer.PREVIEW_IMAGE_STATE)
			{	
			}
			else
			{
				try
				{
					this.moreInfoView.previousState = this.currentState;
					this.previewImage.previousState = this.currentState;
					this.embeddedWelcomeView.previousState = this.currentState;
					this.optionsView.previousState = this.currentState;
					this.sharingView.previousState = this.currentState;	
				}
				catch(err:Error)
				{
					
				}
					
			}	
				
			_currentState = str;
			this.dispatchEvent(new Event(NFBPlayer.STATE_UPDATE_EVENT));
		}
		
		public function speedChanged(evt:Event):void
		{
			trace("Speed changed");
			var fileURL:String;
			ComModule.getInstance().setURLs();
			
			if (audioDescriptionOn)
			{
				if (captionsOn)
				{
					if (ComModule.getInstance().latestMovieHasCCDV)
					{
						player.fileType = NFBPyroBrew.FILE_TYPE_CCDV;
					}
					else
					{
						this.controlBar.subtitlesOn = false;
						this.controlBar.closeSubtitles();
						captionsOn = false;
						if (ComModule.getInstance().latestMovieHasDV)
						{
							player.fileType = NFBPyroBrew.FILE_TYPE_DV;
						}
						else
						{
							audioDescriptionOn = false;		
							player.fileType = NFBPyroBrew.FILE_TYPE_NORMAL;
						}
					}
				} 
				else
				{
					if (ComModule.getInstance().latestMovieHasDV)
					{
						player.fileType = NFBPyroBrew.FILE_TYPE_DV;
					}
					else
					{
						audioDescriptionOn = false;		
						player.fileType = NFBPyroBrew.FILE_TYPE_NORMAL;
					}
				}
			}
			else
			{
				if (captionsOn)
				{
					if (ComModule.getInstance().latestMovieHasCC)
					{
						player.fileType = NFBPyroBrew.FILE_TYPE_CC;
					}
					else
					{
						this.controlBar.subtitlesOn = false;
						this.controlBar.closeSubtitles();
						captionsOn = false;
						player.fileType = NFBPyroBrew.FILE_TYPE_NORMAL;
					}
				}
			}
			
			toggleNewFeedURLs();
		}		
		
		public function toggleAudioDescription():void
		{
			var fileURL:String;
			if (audioDescriptionOn)
			{
				audioDescriptionOn = false;
				
				if (captionsOn)
				{
					if (ComModule.getInstance().latestMovieHasCC)
					{
						player.fileType = NFBPyroBrew.FILE_TYPE_CC;
						ComModule.getInstance().setStats("streamFileTypeChanged :CC");
					}
					else
					{
						captionsOn = false;
						this.controlBar.subtitlesOn = false;
						this.controlBar.closeSubtitles();
						player.fileType = NFBPyroBrew.FILE_TYPE_NORMAL;
						ComModule.getInstance().setStats("streamFileTypeChanged :NORMAL");
					}
				}
				else
				{
					captionsOn = false;
					if (this.controlBar.subtitlesOn)
					{
						this.controlBar.subtitlesOn = false;
						this.controlBar.closeSubtitles();
					}
					player.fileType = NFBPyroBrew.FILE_TYPE_NORMAL;
					ComModule.getInstance().setStats("streamFileTypeChanged :NORMAL");
				}
			}	
			else
			{
				this.audioDescriptionOn = true;	
				if (captionsOn)
				{
					if (ComModule.getInstance().latestMovieHasCCDV)
					{
						player.fileType = NFBPyroBrew.FILE_TYPE_CCDV;
						ComModule.getInstance().setStats("streamFileTypeChanged :CCDV");
					}
					else
					{
						captionsOn = false;
						this.controlBar.subtitlesOn = false;
						this.controlBar.closeSubtitles();
						if (ComModule.getInstance().latestMovieHasDV)
						{
							player.fileType = NFBPyroBrew.FILE_TYPE_DV;
							ComModule.getInstance().setStats("streamFileTypeChanged :DV");
						}
						else
						{
							this.audioDescriptionOn = false;
							player.fileType = NFBPyroBrew.FILE_TYPE_NORMAL;
							ComModule.getInstance().setStats("streamFileTypeChanged :NORMAL");
						}
					}
				}	
				else
				{
					if (ComModule.getInstance().latestMovieHasDV)
					{
						player.fileType = NFBPyroBrew.FILE_TYPE_DV;
						ComModule.getInstance().setStats("streamFileTypeChanged :DV");
					}
					else
					{
						this.audioDescriptionOn = false;
						this.controlBar.subtitlesOn = false;
						this.controlBar.closeSubtitles();
						player.fileType = NFBPyroBrew.FILE_TYPE_NORMAL;
						ComModule.getInstance().setStats("streamFileTypeChanged :NORMAL");
					}
					
				}
			}	
			
			toggleNewFeedURLs();
		}  
		
		public function toggleCloseCaptions():void
		{
			if (captionsOn)
			{
				captionsOn = false;
				if (ComModule.getInstance().latestMovieHasDV)
				{
					player.fileType = NFBPyroBrew.FILE_TYPE_DV;
					ComModule.getInstance().setStats("streamFileTypeChanged :DV");
				}
				else
				{
					player.fileType = NFBPyroBrew.FILE_TYPE_NORMAL;
					ComModule.getInstance().setStats("streamFileTypeChanged :NORMAL");
				}
				this.controlBar.subtitlesOn = false;
				this.controlBar.closeSubtitles();
				return;
			}
			else
			{
				captionsOn = true;
				if (audioDescriptionOn)
				{
					if (ComModule.getInstance().latestMovieHasCCDV)
					{
						player.fileType = NFBPyroBrew.FILE_TYPE_CCDV;
						ComModule.getInstance().setStats("streamFileTypeChanged :CCDV");
						this.controlBar.subtitlesOn = true;
						this.controlBar.openSubtitles();
					}
					else
					{
						audioDescriptionOn = false;
						if (ComModule.getInstance().latestMovieHasCC)
						{
							player.fileType = NFBPyroBrew.FILE_TYPE_CC;
							ComModule.getInstance().setStats("streamFileTypeChanged :CC");
							this.controlBar.subtitlesOn = true;
							this.controlBar.openSubtitles();
						}
						else
						{
							this.controlBar.subtitlesOn = false;
							this.controlBar.closeSubtitles();
							return;
						}		
					}
				}
				else
				{
					if (ComModule.getInstance().latestMovieHasCC)
					{
						player.fileType = NFBPyroBrew.FILE_TYPE_CC;
						ComModule.getInstance().setStats("streamFileTypeChanged :CC");
						this.controlBar.subtitlesOn = true;
						this.controlBar.openSubtitles();
					}
					else
					{
						this.controlBar.subtitlesOn = false;
						this.controlBar.closeSubtitles();
						return;
					}
				}
			}
			toggleNewFeedURLs();
		}
		
		private function toggleNewFeedURLs():void
		{  
			ComModule.getInstance().setURLs();
			if (this.currentState != NFBPlayer.PREVIEW_IMAGE_STATE)
			{
				var tURL:String 	= ComModule.getInstance().latestFileURL;
				var fileURL:String  = ""; 
				
				if (player.time > 0 && player.streamType == Pyro.STREAM_TYPE_PROXIED_PROGRESSIVE)
				{
					var sIndex:Number = tURL.indexOf("start=");
					if (sIndex > 0)
					{
						var prefix:String = tURL.substring(0, sIndex+6);
						prefix += String(player.time);
						
						if (tURL.substring(sIndex+6).indexOf("&") > 0)
						{
							prefix+=tURL.substring(tURL.substring(sIndex+6).indexOf("&"));
						}
					}
					else
					{
						fileURL = tURL;
					}
				}	
				else
				{
					fileURL = tURL;
				}	
				
				player.switchFeed(fileURL);
			}
		}
		
		
		
		
		
						
		public function get autoLoadAudioDescription():Boolean { return _autoLoadAudioDescription; }
		public function set autoLoadAudioDescription(bo:Boolean):void { _autoLoadAudioDescription }
		
		
		public function get backgroundAlpha():Number { return _backgroundAlpha; }
		public function set backgroundAlpha(ba:Number):void 
		{ 
			_backgroundAlpha = ba;
		}
		
		public function get backgroundColor():Number { return _backgroundColor; }
		public function set backgroundColor(bclr:Number):void 
		{
			_backgroundColor = bclr;
		} 
	
		public function get currentState():String { return _currentState; }		
		
		public function get firstRun():Boolean { return this._firstRun; }
		
		public function get outlineAlpha():Number { return _outlineAlpha; }
		public function set outlineAlpha(oa:Number):void 
		{ 
			_outlineAlpha = oa;
		}
		
		public function get outlineColor():Number { return _outlineColor; }
		public function set outlineColor(oclr:Number):void 
		{
			_outlineColor = oclr;
		}
		
		public function get outlineThickness():Number { return _outlineThickness; }
		public function set outlineThickness(ot:Number):void 
		{
			_outlineThickness = ot;
		}
			
		public function get playlistID():String { return _playlistID; }	
			
		public function get registeredViews():Object{ return this._registeredViews; } 
		
		public function get warningMessage():String { return _warningMessage; }
	}
}		
		
